package encoding.convert;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 对指定后缀的文件进行转换编码操作，其余文件制作copy操作
 * @author xiangke
 *
 */
public class Main {
	
	public static String destCharset = "UTF-8";
	/**
	 * 符合此后缀列表的文件才被重新编码
	 */
	public static List<String> suffixList = new ArrayList<String>();
	public static List<String> skipList = new ArrayList<String>();
	static {
		suffixList.add(".java");
		suffixList.add(".jsp");
		suffixList.add(".js");
		suffixList.add(".htm");
		suffixList.add(".html");
		
		skipList.add("E:\\workspace-ljr\\oa\\.svn");
		skipList.add("E:\\workspace-ljr\\oa\\.classpath");
		skipList.add("E:\\workspace-ljr\\oa\\.project");
	}

	public static void main(String[] args) throws Exception {
		String from = "E:\\workspace-ljr\\oa";
		String to = "E:\\workspace-ljr\\oa-bak2";
		convert(from, to);
	}

	
	/**
	 * 将from文件夹以及子文件夹内的所有文件进行编码格式转换，转换后的文件存放在to文件夹内<br>
	 * 所有文件被转换为{destCharset}编码
	 */
	private static void convert(String from, String to) throws Exception {
		File[] files = new File(from).listFiles();
		for (File f : files) {
			/**
			 * 排除某一个文件或者文件夹
			 */
			if (isSkipFile(f)) {
				continue;
			}
			if (f.isDirectory()) {
				convert(f.getPath(), to + File.separator + f.getName());
			} else {
				convertFile(f, to);
			}
		}
	}

	private static boolean isSkipFile(File f) {
		String path = f.getPath();
		return skipList.contains(path);
	}


	/**
	 * 将f文件重新编码，编码后的文件放在to文件夹
	 */
	private static void convertFile(File f, String to) throws Exception {
		String newFile = to + File.separator + f.getName();
		if (isCopyOnly(f)) {
			System.out.println("copy file " + f.getPath());
			copyFile(f, newFile);
		} else {
			System.out.println("convert file " + f.getPath());
			copyAndConvertFile(f, newFile);
		}
	}


	/**
	 * 将oldFile复制到newFilePath表示的文件，并进行重新编码操作<br>
	 * @param oldFile 被复制的文件
	 * @param newFilePath String类型，文件全路径，代表复制到的目标文件
	 */
	public static void copyAndConvertFile(File oldFile, String newFilePath) throws Exception {
		String charset = getFileEncoding(oldFile);
		if ("void".equals(charset)) {
			copyFile(oldFile, newFilePath);
			return;
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(oldFile), charset));
		File newfile = new File(newFilePath);
		if (!newfile.getParentFile().exists()) {
			newfile.getParentFile().mkdirs();
		}
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newfile), destCharset));
		int read;
		char[] cbuf = new char[2048];
		while ((read = br.read(cbuf)) != -1) {
			bw.write(cbuf, 0, read);
		}
		br.close();
		bw.flush();
		bw.close();
	}
	
	/**
	 * 字节流复制文件，将oldFile复制到newFilePath表示的文件<br>
	 * @param oldFile 被复制的文件
	 * @param newFilePath String类型，文件全路径，代表复制到的目标文件
	 */
	public static void copyFile(File oldFile, String newFilePath) throws Exception {
		File newfile = new File(newFilePath);
		if (!newfile.getParentFile().exists()) {
			newfile.getParentFile().mkdirs();
		}
		FileOutputStream fos = new FileOutputStream(newfile);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		FileInputStream fis = new FileInputStream(oldFile);
		BufferedInputStream bis = new BufferedInputStream(fis);
		byte[] buf = new byte[2048];
		int read;
		while ((read = bis.read(buf)) != -1) {
			bos.write(buf, 0, read);
		}
		bis.close();
		bos.close();
	}


	/**
	 * 是否仅复制文件<br>
	 * 文件后缀包含在suffixList中时，要对其进行重新编码，isCopyOnly方法返回false<br>
	 * 反之返回true
	 */
	private static boolean isCopyOnly(File f) {
		String fileName = f.getName();
		String fileSuffix = getSuffix(fileName);
		return !suffixList.contains(fileSuffix);
	}
	
	public static String getSuffix(String str) {
		String suffix = "";
		 int index = str.lastIndexOf(".");
		 if (index != -1) {
		 	suffix = str.substring(index, str.length());;
		 }
		
//		String[] strs = str.split("\\.");
//		if (strs.length > 0) {
//			suffix = strs[strs.length - 1];
//		}
		return suffix;
	}



	/**
	 * 获取文件的编码格式<br>
	 * 无法获取文件的编码格式或获取文件的编码格式时出现异常，返回字符串void
	 */
	private static String getFileEncoding(File f) throws IOException {
		String charset = "";
		try {
			CpdetectorEncoding ce = new CpdetectorEncoding();
			charset = ce.getEncoding(f.getPath(), false).name();
		} catch (Exception e) {
			charset = "void";
		}
		return charset;
	}

}
